#include "net/base/connection.h"
#include "net/base/client_connection.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/cmd_flags.h"
#include "gtest/gtest.h"
#include "strings/numbers.h"
#include <signal.h>

DEFINE_int32(port, 12345, "");

class TestServer : public ServerConnection {
 public:
  TestServer(int port) : ServerConnection(port) {
  }
  virtual void HandleRead(int sockfd, char* buffer, int size) {
    string s(buffer, size);
    LOG(INFO) << "Recv " << s.size() << " " << s;
    if (s.size() > 1) s.resize(s.size() - 1);
    s += " back\n";
    Send(sockfd, s.c_str(), s.size());
    //Disconnect(sockfd);
    delete[] buffer;
  }
  virtual void HandleConnect(int fd) {
    LOG(INFO) << "Connected";
  }
  virtual void HandleDisconnect(int fd) {
    LOG(INFO) << "Disconnect";
  }
};

void TestClient(int idx) {
  sleep(idx);
  ClientConnection conn("127.0.0.1", FLAGS_port);
  conn.Connect();
  string s = "msg ";
  s.append(IntToString(idx));
  s.append("\n");
  sleep(2);
  conn.Send(s.c_str(), s.size());
  LOG(INFO) << "Sent: " << s;
  sleep(1);
  s.resize(s.size() - 1);
  s += " new\n";
  conn.Send(s.c_str(), s.size());
  LOG(INFO) << "ok";
  conn.Send(s.c_str(), s.size());
  LOG(INFO) << "ok";

  char result[100];
  int size = conn.Recv(result, sizeof(result));
  LOG(INFO) << "Recv: " << size << " " << string(result, size);
  size = conn.Recv(result, sizeof(result));
  LOG(INFO) << "Recv: " << size << " " << string(result, size);
  size = conn.Recv(result, sizeof(result));
  LOG(INFO) << "Recv: " << size << " " << string(result, size);

  sleep(1);
  conn.Close();
}

void SigPipe(int i) {
  LOG(INFO) << "sig pipe";
}

TEST(ConnectionTest, TestServerConnection) {
  signal(SIGPIPE, &SigPipe);

  PollRunner runner(4);
  TestServer server(FLAGS_port);
  server.StartListen();
  server.SetPollRunner(&runner);
  DefaultExecutor executor(5);
  for (int i = 0; i < 1; ++i) {
    executor.Add(NewCallback(&TestClient, i));
  }
  runner.Loop();
}
